home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
pgp20src.zip
/
SYSTEM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-17
|
14KB
|
754 lines
/*
* system.c
*
* Routines specific for non-MSDOS implementations of pgp.
*
* Modified 24-Jun-92 HAJK
* Adapt for VAX/VMS.
*/
#include <stdio.h>
#include "pgp.h"
/*===========================================================================*/
/*
* UNIX
*/
#ifdef UNIX
/*
* Define USE_SELECT to use the select() system call to check if
* keyboard input is available. Define USE_NBIO to use non-blocking
* read(). If you don't define anything the FIONREAD ioctl() command
* will be used.
*
* Define NOTERMIO if you don't have the termios stuff
*/
#include <sys/types.h>
#include <fcntl.h>
#ifndef NeXT
#include <unistd.h>
#endif
#ifndef NOTERMIO
#ifndef M_XENIX
#include <termios.h>
#else
#include <termio.h>
#endif /* not M_XENIX */
#else
#include <sgtty.h>
#endif
#ifdef USE_SELECT
#include <sys/time.h>
#else
#ifndef USE_NBIO
#include <sys/ioctl.h> /* for FIONREAD */
#ifndef FIONREAD
#define FIONREAD TIOCINQ
#endif
#endif
#endif
#include <signal.h>
static void setsigs(void);
static void rmsigs(void);
static void sig1(int);
static void sig2(int);
void breakHandler(int);
static int ttyfd= -1;
#ifndef M_XENIX
static void (*savesig)(int);
#else
static int (*savesig)(int);
#endif
void ttycbreak(void);
void ttynorm(void);
#ifndef NOTERMIO
#ifndef M_XENIX
static struct termios itio, tio;
#else
static struct termio itio, tio;
#endif /* not M_XENIX */
#else
static struct sgttyb isg, sg;
#endif
#ifdef USE_NBIO
static int kbuf= -1; /* buffer to store char read by kbhit() */
static int fflags;
#endif
static int gottio = 0;
void ttycbreak(void)
{
if (ttyfd == -1) {
if ((ttyfd = open("/dev/tty", O_RDWR)) < 0) {
fprintf(stderr, "cannot open tty, using stdin\n");
ttyfd = 0;
}
}
#ifndef NOTERMIO
#ifndef M_XENIX
if (tcgetattr(ttyfd, &tio) < 0)
#else
if (ioctl(ttyfd, TCGETA, &tio) < 0)
#endif /* not M_XENIX */
{ fprintf (stderr, "\nUnable to get terminal characteristics: ");
perror("ioctl");
exitPGP(1);
}
itio = tio;
setsigs();
gottio = 1;
#ifdef USE_NBIO
tio.c_cc[VMIN] = 0;
#else
tio.c_cc[VMIN] = 1;
#endif
tio.c_cc[VTIME] = 0;
tio.c_lflag &= ~(ECHO|ICANON);
#ifndef M_XENIX
tcsetattr (ttyfd, TCSAFLUSH, &tio);
#else
ioctl(ttyfd, TCSETAW, &tio);
#endif /* not M_XENIX */
#else
if (ioctl(ttyfd, TIOCGETP, &sg) < 0)
{ fprintf (stderr, "\nUnable to get terminal characteristics: ");
perror("ioctl");
exitPGP(1);
}
isg = sg;
setsigs();
gottio = 1;
sg.sg_flags |= CBREAK;
sg.sg_flags &= ~ECHO;
ioctl(ttyfd, TIOCSETP, &sg);
#endif /* !NOTERMIO */
#ifdef USE_NBIO
if ((fflags = fcntl(ttyfd, F_GETFL)) != -1)
fcntl(ttyfd, F_SETFL, fflags|O_NDELAY);
#endif
}
void ttynorm(void)
{ gottio = 0;
#ifdef USE_NBIO
if (fcntl(ttyfd, F_SETFL, fflags) == -1)
perror("fcntl");
#endif
#ifndef NOTERMIO
#ifndef M_XENIX
tcsetattr (ttyfd, TCSAFLUSH, &itio);
#else
ioctl(ttyfd, TCSETAW, &itio);
#endif /* not M_XENIX */
#else
ioctl(ttyfd, TIOCSETP, &isg);
#endif
rmsigs();
}
static void sig1 (int sig)
{
#ifndef NOTERMIO
#ifndef M_XENIX
tcsetattr (ttyfd, TCSANOW, &itio);
#else
ioctl(ttyfd, TCSETAW, &itio);
#endif /* not M_XENIX */
#else
ioctl(ttyfd, TIOCSETP, &isg);
#endif
signal (sig, SIG_DFL);
if (sig == SIGINT)
breakHandler(SIGINT);
kill (getpid(), sig);
}
static void sig2 (int sig)
{ if (gottio)
ttycbreak();
else
setsigs();
}
static void setsigs(void)
{ savesig = signal (SIGINT, sig1);
#ifdef SIGTSTP
signal (SIGCONT, sig2);
signal (SIGTSTP, sig1);
#endif
}
static void rmsigs(void)
{ signal (SIGINT, savesig);
#ifdef SIGTSTP
signal (SIGCONT, SIG_DFL);
signal (SIGTSTP, SIG_DFL);
#endif
}
#ifndef CRUDE
int kbhit(void)
/* Return TRUE if there is a key to be read */
{
#ifdef USE_SELECT /* use select() system call */
struct timeval t;
fd_set n;
int r;
timerclear(&t);
FD_ZERO(&n);
FD_SET(ttyfd, &n);
r = select(32, &n, NULL, NULL, &t);
if (r == -1) {
perror("select");
exitPGP(1);
}
return r > 0;
#else
#ifdef USE_NBIO /* use non-blocking read() */
unsigned char ch;
if (kbuf >= 0)
return(1);
if (read(ttyfd, &ch, 1) == 1) {
kbuf = ch;
return(1);
}
return(0);
#else
long lf;
if (ioctl(ttyfd, FIONREAD, &lf) == -1) {
perror("ioctl: FIONREAD");
exitPGP(1);
}
return(lf);
#endif
#endif
}
#endif /* !CRUDE */
int getch(void)
{
char c;
#ifdef USE_NBIO
while (!kbhit()); /* kbhit() does the reading */
c = kbuf;
kbuf = -1;
#else
read(ttyfd, &c, 1);
#endif
return(c);
}
#ifdef BSD_OLD
void *memset(s, c, n)
void *s;
register int c, n;
{
register char *p = s;
++n;
while (--n)
*p++ = c;
return(s);
}
int memcmp(s1, s2, n)
register unsigned char *s1, *s2;
register int n;
{
if (!n)
return(0);
while (--n && *s1 == *s2) {
++s1;
++s2;
}
return(*s1 - *s2);
}
void *memcpy(s1, s2, n)
register char *s1, *s2;
register int n;
{
char *p = s1;
++n;
while (--n)
*s1++ = *s2++;
return(p);
}
#endif /* BSD_OLD */
#ifdef M_XENIX /* XENIX/286 specific stuff */
int remove(name)
char *name;
{
return unlink(name);
}
int rename(old, new)
register char *old, *new;
{
(void) unlink(new);
if (link(old, new) < 0)
return -1;
if (unlink(old) < 0) {
(void) unlink(new);
return -1;
}
return 0;
}
#endif /* M_XENIX */
#endif /* UNIX */
/*===========================================================================*/
/*
* VMS
*/
#ifdef VMS /* kbhit()/getch() equivalent */
/*
* This code defines an equivalent version of kbhit() and getch() for
* use under VAX/VMS, together with an exit handler to reset terminal
* characteristics.
*
* This code assumes that kbhit() has been invoked to test that there
* are characters in the typeahead buffer before getch() is invoked to
* get the answer.
*/
#include <descrip.h>
#include <iodef.h>
#ifdef VAXC
#include <ttdef.h>
#include <tt2def.h>
#include <dcdef.h>
#else /* Probably GNU */
#include <vms/$ttdef.h>
#include <vms/$tt2def.h>
#include <vms/$dcdef.h>
#endif /* VAXC */
static volatile short _kbhitChan_ = 0;
static volatile struct IOSB {
unsigned short sts;
unsigned short byteCount;
unsigned short terminator;
unsigned short terminatorSize;
} iosb;
static $DESCRIPTOR (kbdev_desc, "SYS$COMMAND:");
static volatile struct {
char Class;
char Type;
unsigned short BufferSize;
unsigned int Mode;
int ExtChar;
} CharBuf, OldCharBuf;
void kbhit_handler(int *sts)
{
int mysts;
CharBuf.Mode = OldCharBuf.Mode;
CharBuf.ExtChar = OldCharBuf.ExtChar;
CharBuf.Mode &= ~TT$M_NOECHO;
CharBuf.ExtChar &= ~TT2$M_PASTHRU;
if ((mysts = sys$qiow (
0,
_kbhitChan_,
IO$_SETMODE,
&iosb,
0,
0,
&CharBuf,
12,
0,
0,
0,
0)) & 01) mysts = iosb.sts;
(void) sys$dassgn (
_kbhitChan_);
_kbhitChan_ = 0;
if (!(mysts & 01)) {
fprintf(stderr,"\nFailed to reset terminal characteristics!");
(void) lib$signal(mysts);
}
}
unsigned int exsts;
static struct {
int link;
void *rtn;
int argcnt;
int *stsaddr;
} exhblk = { 0, &(kbhit_handler), 1, &(exsts)};
int kbhit()
{
int sts = 1;
struct {
unsigned short TypAhdCnt;
char FirstChar;
char Reserved[5];
} TypCharBuf;
if (_kbhitChan_ == 0) {
if ((sts = sys$assign (
&kbdev_desc,
&_kbhitChan_,
0,
0)) & 1 == 0) lib$stop(sts);
if ((sts = sys$qiow (
0,
_kbhitChan_,
IO$_SENSEMODE,
&iosb,
0,
0,
&CharBuf,
12,
0,
0,
0,
0)) & 01) sts = iosb.sts;
if (sts & 01) {
if (!(CharBuf.Class & DC$_TERM)) {
fprintf(stderr,"\nNot running on a terminal");
exitPGP(1);
} else {
OldCharBuf.Mode = CharBuf.Mode;
OldCharBuf.ExtChar = CharBuf.ExtChar;
CharBuf.Mode |= TT$M_NOECHO;
CharBuf.ExtChar |= TT2$M_PASTHRU;
if ((sts = sys$qiow (
0,
_kbhitChan_,
IO$_SETMODE,
&iosb,
0,
0,
&CharBuf,
12,
0,
0,
0,
0)) & 01) sts = iosb.sts;
if (sts & 01) {
/*
** Declare Exit Handler
*/
(void) sys$dclexh (&exhblk);
} else {
fprintf(stderr,"\nFailed to set terminal characteristics!");
(void) lib$signal(sts);
exitPGP(1);
}
}
}
}
/*
** Get typeahead count
*/
if ((sts = sys$qiow (
0,
_kbhitChan_,
IO$_SENSEMODE | IO$M_TYPEAHDCNT,
&iosb,
0,
0,
&TypCharBuf,
8,
0,
0,
0,
0)) & 01) sts = iosb.sts;
if (sts & 01) return(TypCharBuf.TypAhdCnt>0);
(void) lib$signal(sts);
exitPGP(1);
}
int getch()
{
unsigned int sts;
volatile char CharBuf;
if ((sts = sys$qiow (
0,
_kbhitChan_,
IO$_READVBLK,
&iosb,
0,
0,
&CharBuf,
1,
0,
0,
0,
0)) & 01) sts = iosb.sts;
if (sts & 01) return ((int) CharBuf);
fprintf(stderr,"\nFailed to get character");
(void) lib$signal(sts);
}
ttynorm()
{
int sts;
if (_kbhitChan_ != 0) {
(void) SYS$CANEXH(&exhblk);
kbhit_handler(&sts);
}
}
void ttycbreak ()
{
ttynorm();
}
unsigned long vms_clock_bits[2]; /* VMS Hardware Clock */
const long vms_ticks_per_update = 100000L; /* Clock update int. */
#endif /* VMS */
/*========================================================================*/
/*
* AMIGA
*/
#ifdef AMIGA /* Amiga-specific stuff */
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <libraries/dosextens.h>
#ifdef LATTICE
#include <proto/exec.h>
#include <proto/dos.h>
#endif /* LATTICE */
extern FILE *pgpout;
extern int aecho;
FILE *tmpfile()
{
FILE *fp;
if ((fp=fopen("tmpfile.tmp","w+b"))==NULL) {
perror("tmpfile.tmp");
return(NULL);
}
return(fp);
}
/* amiga version of getch()
Cor Bosman , jul-22-92
*/
sendpacket(struct MsgPort *rec,LONG action,LONG arg1)
{
struct StandardPacket *pkt;
struct msgPort *rp;
LONG res1 = 0L;
if (rp = (struct MsgPort *)CreatePort(NULL,0L)) {
if (pkt = (struct StandardPacket *)\
AllocMem(sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR)) {
pkt->sp_Msg.mn_Node.ln_Name = (BYTE *)&pkt->sp_Pkt;
pkt->sp_Pkt.dp_Link = &pkt->sp_Msg;
pkt->sp_Pkt.dp_Port = rp;
pkt->sp_Pkt.dp_Type = action;
pkt->sp_Pkt.dp_Arg1 = arg1;
PutMsg(rec,&pkt->sp_Msg);
WaitPort(rp);
GetMsg(rp);
res1 = pkt->sp_Pkt.dp_Res1;
FreeMem((UBYTE*)pkt,sizeof(struct StandardPacket));
}
DeletePort(rp);
}
return(res1);
}
/* ttycbreak for amiga.
* Cor Bosman , jul-30-92
*/
void ttycbreak()
{
BPTR in,out;
char buf[128];
struct MsgPort *ch;
in=Input();
out=Output();
ch = ((struct FileHandle *)BADDR(in))->fh_Type;
sendpacket(ch,ACTION_SCREEN_MODE,-1L);
}
/* ttynorm for amiga
* Cor Bosman , jul-30-92
*/
void ttynorm()
{
BPTR in,out;
char buf[128];
struct MsgPort *ch;
in=Input();
out=Output();
ch = ((struct FileHandle *)BADDR(in))->fh_Type;
sendpacket(ch,ACTION_SCREEN_MODE,0L);
}
char getch(void)
{
char buf[128];
BPTR in,out;
in = Input();
out = Output();
Read(in,buf,1);
if (aecho)
Write(out, buf, 1);
return(buf[0]);
}
/* kbhit() function for amiga.
* Cor Bosman , jul-30-92
*/
int kbhit()
{
if(WaitForChar(Input(), 1)) return 1;
return 0;
}
#ifdef LATTICE
/*
* Lattice-C ^C-Handler
*/
int CXBRK()
{
BPTR in,out;
struct MsgPort *ch;
in=Input();
out=Output();
/* it might happen we catch a ^C while in cbreak mode.
* so always set the screen to the normal mode.
*/
ch = ((struct FileHandle *)BADDR(in))->fh_Type;
sendpacket(ch, ACTION_SCREEN_MODE, 0L);
fprintf(pgpout, "\n*** Program Aborted.\n");
exitPGP(6); /* INTERRUPT */
}
#endif
#endif /* AMIGA */
/*===========================================================================*/
/*
* other stuff for non-MSDOS systems
*/
#ifdef ATARI
#include <string.h>
#endif
#if !defined(MSDOS) && !defined(ATARI)
#include <ctype.h>
char *strlwr(char *s)
{ /*
** Turns string s into lower case.
*/
int c;
char *p = s;
while (c = *p)
*p++ = tolower(c);
return(s);
}
#endif /* !MSDOS && !ATARI */
#ifdef strstr
#undef strstr
/* Not implemented on some systems - return first instance of s2 in s1 */
char *mystrstr (char *s1, char *s2)
{ int i;
char *strchr();
if (!s2 || !*s2)
return s1;
for ( ; ; )
{ if (!(s1 = strchr (s1, *s2)))
return s1;
for (i=1; s2[i] && (s1[i]==s2[i]); ++i)
;
if (!s2[i])
return s1;
++s1;
}
}
#endif /* strstr */
#ifdef fopen
#undef fopen
#ifdef ATARI
#define F_BUF_SIZE 8192 /* seems to be a good value ... */
FILE *myfopen(const char *filename, const char *mode)
/* Open streams with larger buffer to increase disk I/O speed. */
/* Adjust F_BUF_SIZE to change buffer size. */
{
FILE *f;
if ( (f = fopen(filename, mode)) != NULL )
if (setvbuf(f, NULL, _IOFBF, F_BUF_SIZE)) /* no memory? */
{
fclose(f); /* then close it again */
f = fopen(filename, mode); /* and try again in normal mode */
}
return(f); /* return either handle or NULL */
}
#else /* ATARI */
/* Remove "b" from 2nd arg */
FILE *myfopen(char *filename, char *type)
{ char buf[10];
buf[0] = *type++;
if (*type=='b')
++type;
strcpy(buf+1,type);
return fopen(filename, buf);
}
#endif /* not ATARI */
#endif /* fopen */